from __future__ import with_statement
import threading
from contextlib import contextmanager

@contextmanager
def apply_on_timeout(sec, func, args):
    if sec is None:
        yield
    else:
        t = threading.Timer(sec, func, args)
        t.start()
        try:
            yield
        finally:
            t.cancel()

if __name__ == '__main__':
    import sys, time
    write = sys.stdout.write
    
    with apply_on_timeout(2, write, ("This message must NOT be shown\n",)):
        time.sleep(1)
        write("This message is shown at 1st\n")
    
    write("This message is shown at 2nd\n")
    
    with apply_on_timeout(1, write, ("This message is shown at 3rd\n",)):
        time.sleep(2) # this statement causes timeout!
        write("This message is shown at 4th\n")
    
    write("This message is shown at 5th\n")
